/******************************************************************************* 
  Copyright (C), 1988-2020, zeno Tech. Co., Ltd.
  Description:   AUDIO模块  
  Function List:     
  History:
    <wyg -- 2022-10-18>  创建
*******************************************************************************/ 

/*=============================================================================
                                 Includes                                  
 =============================================================================*/
#include "audioPriv.h" 
#include "audioFaac.h"

/*=============================================================================
                               Macro Definition
 =============================================================================*/

//#define ADEC_CALL_BACK

/*=============================================================================
                        Local Structures and Typedef 
 =============================================================================*/


/*=============================================================================
                             Extern Variables                                  
=============================================================================*/
extern unsigned long long vdo_get_time();
extern int AUDIO_GetOutSamples(int sampleRate, int *nbSamples);
extern int AUDIO_GetResamplerLen(int sampleRate, int depth, int channels, int *dealLen);
/*=============================================================================
                             Local Variables                                  
 =============================================================================*/
static pthread_t    decGetDataThd;

/*=============================================================================
                             Function Definition                                  
 =============================================================================*/ 
/*******************************************************************************
    Function:     ADEC_GetFullFromList
    Description:  从full对列取数据
    Input:        - pThiz: 音频输入接口指针
    Output:       - pListPacket：获取队列的节点数据指针
    Return:       0: 操作成功
                  -1: 操作失败
    Others:       无
  *******************************************************************************/
int ADEC_GetFullFromList(ADEC_ctl_t *pAdecCtl, ACOMM_listInfo_t* pListPacket) 
{
    int ret = 0;
    if (!pAdecCtl)
    {
        LOG_PrintError("pAdecCtl is NULL\n");
        return -1;
    }

    ACOMM_listInfo_t* pListFrame = NULL; 

    ///get full node from list
    pthread_mutex_lock(&pAdecCtl->adecBufLock);            
    if(!list_empty(&pAdecCtl->fullBuf))
    {
        pListFrame = list_first_entry(&pAdecCtl->fullBuf, ACOMM_listInfo_t, list);
        list_del(&pListFrame->list);

        memcpy(pListPacket, pListFrame,sizeof(ACOMM_listInfo_t)); //浅拷贝
        pListPacket->revered = pListFrame; //记录指针后续返还
        pthread_mutex_unlock(&pAdecCtl->adecBufLock);

        //printf("ADEC_GetFullFromList:: bufLen=%d\n",pListFrame->len);
    }
    else
    {
        pthread_mutex_unlock(&pAdecCtl->adecBufLock);

        //LOG_PrintError("fullBuf is NULL\n");
        ret = -1;
    }

    return ret;
}

 /*******************************************************************************
    Function:     AI_PutEmptyToList
    Description:  将节点放回empty队列
    Input:        - pThiz: 音频输入接口指针
                  - pListPacket：放回队列的节点数据指针
    Output:       无
    Return:       0: 操作成功
                  -1: 操作失败
    Others:       无
  *******************************************************************************/
int ADEC_PutEmptyToList(ADEC_ctl_t *pAdecCtl, ACOMM_listInfo_t* pListPacket) 
{
    if (!pAdecCtl)
    {
        LOG_PrintError("pAdecCtl is NULL\n");
        return -1;
    }    

    ACOMM_listInfo_t* pListFrame = (ACOMM_listInfo_t*)pListPacket->revered; 

    ///put empty node to list
    pthread_mutex_lock(&pAdecCtl->adecBufLock); 
    list_add_tail(&pListFrame->list, &pAdecCtl->emptyBuf);
    pthread_mutex_unlock(&pAdecCtl->adecBufLock);
    
    return 0;
}


 
static void *ADEC_GetDataThd(void *parg)
{
    ADEC_ctl_t *pDecCtl = (ADEC_ctl_t *)parg;
    if (!pDecCtl)
    {
        LOG_PrintInfo("pDecCtl is NULL\n");
        return NULL;
    }

    AMIX_composeCtl_t* pComposeCtl = audioCtl_g.pComposeCtl;
    if (!pComposeCtl)
    {
        LOG_PrintInfo("pComposeCtl is NULL\n");
        return NULL;
    }

    AAD_ctl_t *pAadCtl = NULL;

    char getData[MAX_PCM_SIZE] = {0};
    int getLen = 0;
    int readLen = 0;
    
    char procBuf[MAX_PCM_SIZE] = {0};
    int procLen = 0;

    char midSaveBuf[MAX_PCM_SIZE] = { 0 };
    int outLen = 0;
    int midPos = 0;

    static long long cntTmp = 0;
    int dealLen = 0;
    unsigned long long ts = 0;
    unsigned long long  runtime = 0;
    uint64 lastFramPts = 0;

    while(1)
    {
        if(pDecCtl->adecState != ADEC_START)
        {
            usleep(15*1000); //时间待测试 todo
            continue;
        }

        pthread_mutex_lock(&audioCtl_g.adecMutex);
        pAadCtl = pDecCtl->pAadCtl; 
        
        //LOG_PrintError("ADEC_GetDataThd pAadCtl->ringBuf.dataLen=%d,pDecCtl->resamplerLen=%d\n",pAadCtl->ringBuf.dataLen, pDecCtl->resamplerLen);
        if(pAadCtl && (pAadCtl->ringBuf.dataLen >= pDecCtl->resamplerLen))
        {
            memset(getData, 0, sizeof(getData)/sizeof(char));

            readLen = (pDecCtl->resamplerLen > MAX_PCM_SIZE) ? MAX_PCM_SIZE : pDecCtl->resamplerLen;
            
            getLen = AAC_DecGetStream(pAadCtl, getData, readLen);

            pthread_mutex_unlock(&audioCtl_g.adecMutex);

            dealLen = readLen;

            if (pDecCtl->adecFormat.frequency == AUDIO_RESAMPLE_44100HZ)
            {
                outLen = AUDIO_RESAMPLER_TIME_44100_BASE;
            }
            else {
                outLen = pDecCtl->nbSamples;
            }
            
            for(int j = 0; j < 1; ++j)
            {                
                memset(procBuf, 0, sizeof(procBuf)/sizeof(char));
                
                if (2 == pDecCtl->adecFormat.channels)
                {
                    //双声道变单声道
                    for(int i = 0; i < dealLen/2; i+=2)
                    {
                        procBuf[i] = getData[dealLen * j + 2 * i];
                        procBuf[i + 1] = getData[dealLen * j + 2 * i + 1];
                    }
                    procLen = dealLen/2;
                    procLen /= 2;
                }
                else if (1 == pDecCtl->adecFormat.channels)
                {
                    memcpy(procBuf, getData + dealLen * j , dealLen);
                    procLen = dealLen;
                    procLen /= 2;
                }
                else
                {
                    usleep(10 * 1000);
                    //LOG_PrintWarn("channels: %d is not support!\n", pDecCtl->adecFormat.channels);
                    continue;
                }

                ACOMM_listInfo_t *pListFrame = NULL;
               
                if ((pDecCtl->resampler)
                    && (pDecCtl->adecFormat.frequency != AUDIO_RESAMPLER_BASE))
                {
                    speex_resampler_process_int(pDecCtl->resampler, 0, (short*)procBuf, &procLen, (short*)(midSaveBuf + midPos), &outLen);
                    midPos += 2 * outLen;    
                }
                else
                {
                    memcpy(midSaveBuf + midPos, procBuf, 2 * procLen);
                    midPos += 2 * procLen;
                }

                if (midPos >= AUDIO_RESAMPLE_OUT_TO_LIST_LEN) {
                    pthread_mutex_lock(&pDecCtl->adecBufLock);
                    if (!list_empty(&pDecCtl->emptyBuf))
                    {
                        pListFrame = list_first_entry(&pDecCtl->emptyBuf, ACOMM_listInfo_t, list);
                        list_del(&pListFrame->list);
                        pthread_mutex_unlock(&pDecCtl->adecBufLock);
                        memset(pListFrame->pBuf, 0, pDecCtl->maxBufLen);
                        memcpy(pListFrame->pBuf, midSaveBuf, AUDIO_RESAMPLE_OUT_TO_LIST_LEN);
                        pListFrame->len = AUDIO_RESAMPLE_OUT_TO_LIST_LEN;

                        pListFrame->pts = vdo_get_time();
                        if (lastFramPts == pListFrame->pts)
                        {
                            usleep(1 * 1000);
                            pListFrame->pts += 1; //加1确保连续帧处理数据时间不一样
                        }
                        lastFramPts = pListFrame->pts;
                        //audio_FILE_Write2("/nfsroot/StreamFile/test/audio_dec_out.pcm", midSaveBuf, AUDIO_RESAMPLE_OUT_TO_LIST_LEN);  

                        pthread_mutex_lock(&pDecCtl->adecBufLock);
                        list_add_tail(&pListFrame->list, &pDecCtl->fullBuf);
                        pthread_mutex_unlock(&pDecCtl->adecBufLock);

                        pComposeCtl->newPts[pDecCtl->adecChn] = lastFramPts; //更新buf时间
                        
                    }
                    else {
                        pthread_mutex_unlock(&pDecCtl->adecBufLock);
                        usleep(1 * 1000);
                    }

                    memmove(midSaveBuf , midSaveBuf + AUDIO_RESAMPLE_OUT_TO_LIST_LEN, midPos - AUDIO_RESAMPLE_OUT_TO_LIST_LEN);
                    midPos -= AUDIO_RESAMPLE_OUT_TO_LIST_LEN;
                }      
            }                                               
        }
        else
        {
            pthread_mutex_unlock(&audioCtl_g.adecMutex);
            usleep(5*1000); //时间待测试 todo
        }
    }

    return NULL;
}


static int ADEC_DeinitList(ADEC_ctl_t *pDecCtl)
{
    ACOMM_listInfo_t *pListFrame;
    pthread_mutex_lock(&pDecCtl->adecBufLock);
    
    while (!list_empty(&pDecCtl->fullBuf))
    {
        pListFrame = list_first_entry(&pDecCtl->fullBuf, ACOMM_listInfo_t, list);
        list_del(&pListFrame->list);
        list_add_tail(&pListFrame->list, &pDecCtl->emptyBuf);
    }

    pthread_mutex_unlock(&pDecCtl->adecBufLock);
            
    return 0;
}

 /*******************************************************************************
   Function:     ADEC_SetFormat
   Description:  设置视频编码数据压缩的格式
   Input:        - pThiz: 视频编码接口指针
                 - pFormat 指向视频格式结构AudioDecFormat的指针，
                           NULL表示不编码视频。
   Output:       无
   Return:       0: 操作成功
                 -1: 操作失败
   Others:       无
 *******************************************************************************/
 static int ADEC_SetFormat(struct AudioDecoder *pThiz, AudioDecFormat *pFormat)
 {
     int ret = 0;
     ADEC_ctl_t *pDecCtl;
     
     if (!pThiz || !pFormat)
     {
         LOG_PrintError("Input parameter is NULL\n");
         return -1;
     }
 
     pDecCtl = (ADEC_ctl_t *)pThiz->priv;
     if (!pDecCtl)
     {
         LOG_PrintError("AudioDecoder isn't initialized\n");
         return -1;
     }
 
     pthread_mutex_lock(&audioCtl_g.adecMutex);
 
     if (pDecCtl->adecState != ADEC_STOP)
     {
         LOG_PrintError("adec channel %d is running!\n", pDecCtl->adecChn);
         ret = -1;
         goto mutex_unlock;
     }
        

     ///配置resample参数
     if(pFormat->frequency != pDecCtl->adecFormat.frequency)
     {
         if(pDecCtl->resampler)
         {
             speex_resampler_destroy(pDecCtl->resampler);
         }
         
         pDecCtl->resampler = speex_resampler_init(1, pFormat->frequency, AUDIO_RESAMPLER_BASE, 1, NULL);
         if(!pDecCtl->resampler)
         {
             ret = -1;
             goto mutex_unlock;            
         }
         
         speex_resampler_set_rate(pDecCtl->resampler, pFormat->frequency, AUDIO_RESAMPLER_BASE);
         speex_resampler_skip_zeros(pDecCtl->resampler); 
         

         AUDIO_GetOutSamples(AUDIO_RESAMPLER_BASE, &pDecCtl->nbSamples);
     }

     AUDIO_GetResamplerLen(pFormat->frequency, pFormat->depth, pFormat->channels, &pDecCtl->resamplerLen);


     memcpy(&pDecCtl->adecFormat, pFormat, sizeof(AudioDecFormat));

     LOG_PrintWarn("Adec channel:%d SetFormat, frequency=%d, pFormat->channels=%d\n", pDecCtl->adecChn, pFormat->frequency, pFormat->channels);

 mutex_unlock:  
     pthread_mutex_unlock(&audioCtl_g.adecMutex);
     return ret;
 }


 /*******************************************************************************
  Function:     ADEC_AddRef
  Description:  增加接口引用
  Input:        - pThiz: 视频解码接口指针
  Output:       无
  Return:       0: 操作成功
                -1: 操作失败
  Others:       无
*******************************************************************************/
static int ADEC_AddRef(struct AudioDecoder *pThiz)
{
    ADEC_ctl_t *pDecCtl;

    if (!pThiz)
    {
        LOG_PrintError("Input parameter is NULL\n");
        return -1;
    }

    pDecCtl = (ADEC_ctl_t *)pThiz->priv;
    if (!pDecCtl)
    {
        LOG_PrintError("AudioDecoder isn't initialized\n");
        return -1;
    }
    
    pthread_mutex_lock(&audioCtl_g.adecMutex);

    pDecCtl->refCount++;
    
    pthread_mutex_unlock(&audioCtl_g.adecMutex);
    
    return 0;
}
 /*******************************************************************************
   Function:     ADEC_Release
   Description:  释放接口
   Input:        - pThiz: 视频解码接口指针
   Output:       无
   Return:       0: 操作成功
                 -1: 操作失败
   Others:       无
 *******************************************************************************/
 static int ADEC_Release(struct AudioDecoder *pThiz)
 {
     int ret = 0;
     ADEC_ctl_t *pDecCtl;
     
     if (!pThiz)
     {
         LOG_PrintError("Input parameter is NULL\n");
         return -1;
     }
 
     pDecCtl = (ADEC_ctl_t *)pThiz->priv;
     if (!pDecCtl)
     {
         LOG_PrintError("AudioDecoder isn't initialized\n");
         return -1;
     }
     
     pthread_mutex_lock(&audioCtl_g.adecMutex);
     
     if (pDecCtl->refCount > 1)
     {
         pDecCtl->refCount--;
         goto unlock_mutex;
     }
     
     audioCtl_g.pAdecCtls[pDecCtl->adecChn] = NULL;
     free(pDecCtl);
     
 unlock_mutex:       
     pthread_mutex_unlock(&audioCtl_g.adecMutex);
     return ret;
 }

 /*******************************************************************************
  Function:     ADEC_StartUnlock
  Description:  启动解码,不加锁
  Input:        - pDecCtl: 编码通道控制结构体 
  Output:       无
  Return:       0: 操作成功
                -1: 操作失败
  Others:       无
*******************************************************************************/
static int ADEC_StartUnlock(ADEC_ctl_t *pDecCtl)
{
    int ret = 0;
    if (!pDecCtl)
    {
        LOG_PrintError("AudioDecoder isn't initialized\n");
        return -1;
    }
    
    if (pDecCtl->adecState != ADEC_STOP)
    {
    	LOG_PrintError("vdec state is not stop!\n");
        return -1;
    }

    if(pDecCtl->adecFormat.type == audioEncAAC)
    {
        
        if(!pDecCtl->pAadCtl)
        {
            pDecCtl->pAadCtl = (AAD_ctl_t *)AAC_DecCreat();           
            if (!pDecCtl->pAadCtl)
            {
                LOG_PrintError("AAC_DecCreat failed\n");
                return -1;
            }

            AAC_audioCfg_t pAacCfg = {0};
            pAacCfg.sampleRate = pDecCtl->adecFormat.frequency;
            pAacCfg.bitWidth= pDecCtl->adecFormat.depth;

            ret = AAC_DecSetFormat(pDecCtl->pAadCtl, &pAacCfg);//暂不支持动态更新
            if (ret)
            {
                LOG_PrintError("AAC_DecSetFormat failed!\n");
                return -1;
            }   

             LOG_PrintWarn("AAC_DecCreat success \n");
        }
       
    }

    pDecCtl->adecState = ADEC_START;

    return 0;
}

 /*******************************************************************************
  Function:     ADEC_Start
  Description:  启动解码
  Input:        - pThiz: 视频解码接口指针
  Output:       无
  Return:       0: 操作成功
                -1: 操作失败
  Others:       无
*******************************************************************************/
static int ADEC_Start(struct AudioDecoder *pThiz)
{
    int ret = 0, result;
    ADEC_ctl_t *pDecCtl;
    
    if (!pThiz)
    {
        LOG_PrintError("Input parameter is NULL\n");
        return -1;
    }

    pDecCtl = (ADEC_ctl_t *)pThiz->priv;
    if (!pDecCtl)
    {
        LOG_PrintError("AudioDecoder isn't initialized\n");
        return -1;
    }

    pthread_mutex_lock(&audioCtl_g.adecMutex);

    result = ADEC_StartUnlock(pDecCtl);
    if (result)
    {
        LOG_PrintError("Fail to start encode channel %d!\n", pDecCtl->adecChn);
        ret = -1;
        goto mutex_unlock;
    }

    LOG_PrintInfo("ADEC_Start adecChn:%d success\n",pDecCtl->adecChn);

mutex_unlock:
    pthread_mutex_unlock(&audioCtl_g.adecMutex);
    return ret;
}

/*******************************************************************************
  Function:     ADEC_StopUnlock
  Description:  停止编码,不加锁
  Input:        - pDecCtl: 编码通道控制结构体 
  Output:       无
  Return:       0: 操作成功
                -1: 操作失败
  Others:       无
*******************************************************************************/
static int ADEC_StopUnlock(ADEC_ctl_t *pDecCtl)
{
    int ret = 0;

    LOG_PrintWarn("pDecCtl->adecChn:%d\n", pDecCtl->adecChn);

	if (pDecCtl->adecState == ADEC_STOP)
	{
		LOG_PrintWarn("adec chn %d have been stoped!\n", pDecCtl->adecChn);
		return 0;
	}  

    if(pDecCtl->adecFormat.type == audioEncAAC)
    {
        if(pDecCtl->pAadCtl)
        {
            ret = AAC_DecDestroy(pDecCtl->pAadCtl);
            if (ret)
            {
                LOG_PrintError("AAC_DecDestroy failed \n");
                return -1;
            }

            pDecCtl->pAadCtl = NULL;

            LOG_PrintWarn("AAC_DecDestroy success \n");
        }
    }

    ADEC_DeinitList(pDecCtl);

    pDecCtl->adecState = ADEC_STOP;

    return 0;
}


/*******************************************************************************
  Function:     ADEC_Stop
  Description:  停止解码
  Input:        - pThiz: 视频解码接口指针
  Output:       无
  Return:       0: 操作成功
                -1: 操作失败
  Others:       无
*******************************************************************************/
static int ADEC_Stop(struct AudioDecoder *pThiz)
{
    int ret = 0, result;
    ADEC_ctl_t *pDecCtl;
    
    if (!pThiz)
    {
        LOG_PrintError("Input parameter is NULL\n");
        return -1;
    }

    pDecCtl = (ADEC_ctl_t *)pThiz->priv;
    if (!pDecCtl)
    {
        LOG_PrintError("AudioDecoder isn't initialized\n");
        return -1;
    }
    
    pthread_mutex_lock(&audioCtl_g.adecMutex);
    
    result = ADEC_StopUnlock(pDecCtl);
    if (result)
    {
        LOG_PrintError("Fail to stop encode channel %d!\n", pDecCtl->adecChn);
        ret = -1;
        goto mutex_unlock;
    }

    LOG_PrintWarn("stop success \n");
    

mutex_unlock:
    pthread_mutex_unlock(&audioCtl_g.adecMutex);
    return ret;
}


/// 填充帧数据到视频解码缓冲，非阻塞操作，如果底层缓冲已满，则返回错误。
/// 解码后的图像不一定立即显示，底层还需要进行帧率控制，直到解码后缓冲
/// 有足够空间，才可以填下次数据。
/// 
/// \param [in] thiz 视频解码接口指针
/// \param [in] packet 包数据信息，见AudioDecPacket结构。
/// \retval 0  写成功
/// \retval <0  写失败
static int ADEC_PutPacket(struct AudioDecoder *pThiz, AudioDecPacket *packet)
{
    int ret = 0;
    ADEC_ctl_t *pDecCtl;
    int dataLen = 0;
    
    static unsigned long long ts = 0;
    

    if (!pThiz)
    {
        LOG_PrintError("Input parameter is NULL\n");
        return -1;
    }

    pDecCtl = (ADEC_ctl_t *)pThiz->priv;
    if (!pDecCtl)
    {
        LOG_PrintError("AudioDecoder isn't initialized\n");
        return -1;
    }

    if(pDecCtl->adecState == ADEC_STOP)
    {
        LOG_PrintError("AudioDecoder adecState stop\n");
        return -1;
    }

    //LOG_PrintInfo("ADEC_PutPacket curpts=%llu \n", vdo_get_time());

    pthread_mutex_lock(&audioCtl_g.adecMutex);

    if(pDecCtl->adecFormat.type == audioEncAAC)
    {
        if(pDecCtl->pAadCtl)
        {
            //LOG_PrintError("packet->length =%d\n",packet->length);
            
            dataLen = AAC_DecSendFrame(pDecCtl->pAadCtl, 
                                            packet->buffer,
                                            packet->length);
            if(dataLen <= 0)
            {
                ret = -1;
                goto mutex_unlock;
            }
        }
    }

mutex_unlock:
    pthread_mutex_unlock(&audioCtl_g.adecMutex);  


    //ts = vdo_get_time();
    //printf("ADEC_PutPacket channel:%d, dataLen:%d \n",pDecCtl->adecChn, dataLen);
    return ret;
}

#if 0
int ADEC_PutPacketTest(ADEC_ctl_t *pDecCtl, uchar *pBuf, int len)
{
    LOG_PrintWarn("ADEC_PutPacketTest enter\n");
    int ret = 0;

    if (!pDecCtl)
    {
        LOG_PrintError("AudioDecoder isn't initialized\n");
        return -1;
    }

    if(pDecCtl->adecState == ADEC_STOP)
    {
        LOG_PrintError("AudioDecoder adecState stop\n");
        return -1;
    }

    pthread_mutex_lock(&audioCtl_g.adecMutex);

    if(pDecCtl->adecFormat.type == audioEncAAC)
    {
        if(pDecCtl->pAadCtl)
        {
            {
                LOG_PrintError("packet->length =%d\n",len);
                
                int dataLen = AAC_DecSendFrame(pDecCtl->pAadCtl, 
                                                pBuf,
                                                len);
                if(dataLen <= 0)
                {
                    ret = -1;
                    goto mutex_unlock;
                }

                
                
                
                char getData[4096*2] = {0};
                int getLen = AAC_DecGetStream(pDecCtl->pAadCtl, 
                                                    getData, 
                                                    4096); 
                                                    
                LOG_PrintError("packet->length =%d, dataLenout=%d! remainLen=%d\n",len, dataLen, getLen);

                
            }

            //FILE_write2("/nfsroot/StreamFile/decode.pcm", getData, dataLen);   
        }
    }

mutex_unlock:
    pthread_mutex_unlock(&audioCtl_g.adecMutex);  

    LOG_PrintWarn("ADEC_PutPacketTest leave\n");
    return ret;
}
#endif


/// 清空解码后图像缓冲，被阻塞的putPacket将会立即返回。
/// 
/// \param [in] thiz 视频解码接口指针
/// \retval 0  清空成功
/// \retval <0  清空失败
static int ADEC_Flush(struct AudioDecoder *thiz)
{
    return 0;
}


/// 检查解码后缓冲是否为空，即图像是否已经被全部呈现。
/// 
/// \param [in] thiz 视频解码接口指针
/// \retval 0  非空
/// \retval 1  已空
/// \return <0 检查出错
static int ADEC_Empty(struct AudioDecoder *thiz)
{
    return 0;
}

/*******************************************************************************
  Function:     ADEC_GetCaps
  Description:  得到视频解码设备能力
  Input:        - pThiz: 视频解码接口指针
  Output:       - pDecCaps: 解码能力结构AudioEncCaps指针
  Return:       0: 操作成功
                -1: 操作失败
  Others:       无
*******************************************************************************/
static int ADEC_GetCaps(struct AudioDecoder *pThiz, AudioDecCaps *pDecCaps)
{
    ADEC_ctl_t *pDecCtl;
    
    if ((NULL == pThiz) || (NULL == pDecCaps))
    {
        LOG_PrintError("Input parameter is NULL\n");
        return -1;
    }

    pDecCtl = (ADEC_ctl_t *)pThiz->priv;
    if (!pDecCtl)
    {
        LOG_PrintError("AudioDecoder isn't initialized\n");
        return -1;
    } 
    
    return 0;
}

 /// 创建视频解码接口。创建成功后，如果芯片资源限制，不一定可以正常解码。
 /// 
 /// \param [in] dest 视频解码接口描述结构AudioDecDesc指针
 /// \param [out] audioDecoder 视频解码接口指针的指针
 /// \retval <0 创建失败
 /// \retval 0 创建成功
 int PAL_API createAudioDecoder(AudioDecDesc *pDecDesc, AudioDecoder** ppAudioDecoder)
 {
    int ret = 0, result = 0;
    AudioDecoder *pAudioDecoder = NULL;
    ADEC_ctl_t *pDecCtl = NULL;
    unsigned int descChannel = 0;

    if ((NULL == pDecDesc) || (NULL == ppAudioDecoder))
    {
        LOG_PrintError("Parameter is NULL!\n");
        return -1;
    }

    descChannel = pDecDesc->channel;
    if(descChannel >= ADEC_MAX_CHN_NUM)
    {
        LOG_PrintError("descChannel:%d over maxnum !\n", descChannel);
        return -1;
    }

    pthread_mutex_lock(&audioCtl_g.adecMutex);
    
    pDecCtl = audioCtl_g.pAdecCtls[descChannel];
    if (pDecCtl)
    {
        LOG_PrintInfo("audio decoder has already been created,"
                       "dest = %d\n", 
                       pDecDesc->dest);
        pDecCtl->refCount++;
        *ppAudioDecoder = &pDecCtl->audioDecoder;
        goto mutex_unlock;
    }

    pDecCtl = (ADEC_ctl_t *)malloc(sizeof(ADEC_ctl_t));
    if (!pDecCtl)
    {
        LOG_PrintError("There is no enough memory to allocate AudioDecoder!\n");
        ret = -1;
        goto mutex_unlock;
    }
    memset(pDecCtl, 0, sizeof(ADEC_ctl_t));

    pDecCtl->refCount++;
    pDecCtl->adecState = ADEC_STOP; 
    pDecCtl->adecChn = descChannel;
    pDecCtl->resampler = NULL;
    pDecCtl->pAadCtl = NULL;
    

    ///init list
    int i = 0;
    INIT_LIST_HEAD(&pDecCtl->emptyBuf);
    INIT_LIST_HEAD(&pDecCtl->fullBuf);
    pthread_mutex_init(&pDecCtl->adecBufLock, NULL);
    pDecCtl->maxBufLen = 4096*sizeof(char)*2; //长度待定
    for (i = 0; i < ADEC_ACOMMLIST_LENGTH; i++)
    {
        pDecCtl->listBuf[i].pBuf = (char *)malloc(pDecCtl->maxBufLen); 
        if (!pDecCtl->listBuf[i].pBuf)
        {
            LOG_PrintError("Fail to malloc!\n");
            ret = -1;
            goto free_ctl;
        }
        pDecCtl->listBuf[i].pts = 0;
        pDecCtl->listBuf[i].len = 0;
        list_add_tail(&pDecCtl->listBuf[i].list, &pDecCtl->emptyBuf);
    }


    audioCtl_g.pAdecCtls[descChannel] = pDecCtl;


    pAudioDecoder = &pDecCtl->audioDecoder;
    pAudioDecoder->priv = pDecCtl;
    pAudioDecoder->addRef = ADEC_AddRef;
    pAudioDecoder->release = ADEC_Release;
    pAudioDecoder->getCaps = ADEC_GetCaps;
    pAudioDecoder->start = ADEC_Start;
    pAudioDecoder->stop = ADEC_Stop;
    pAudioDecoder->empty = ADEC_Empty;
    pAudioDecoder->flush = ADEC_Flush;
    pAudioDecoder->putPacket = ADEC_PutPacket;
    pAudioDecoder->setFormat = ADEC_SetFormat;


    *ppAudioDecoder = &pDecCtl->audioDecoder;


#if 1
    /* create data recv thread */
    ret = pthread_create(&decGetDataThd, NULL, ADEC_GetDataThd, pDecCtl);
    if(ret)
    {
        LOG_PrintError("can't create thread: %s\n", strerror(ret));
        ret = -1;
    }
#endif
   
    
    LOG_PrintInfo("Create audioDecoder::%d successfully!\n",descChannel);
    goto mutex_unlock;
    
free_ctl: 
    free(pDecCtl);
    
mutex_unlock:
    pthread_mutex_unlock(&audioCtl_g.adecMutex);
    return ret;
 }

